package com.ehome.emergency.dao;

import com.ehome.emergency.utils.Pager;
import org.hibernate.criterion.DetachedCriteria;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

/**
 * BasicFramework
 *
 * @author: haoxiaolei
 * @date: 2016-02-15 15:55
 * @desc: 公共DAO接口
 */
public interface GenericDao<T, PK extends Serializable> {
    /**
     * 保存
     *
     * @param entity 对象实体
     *
     * @return 保存后的对象
     */
    T save(T entity)  throws Exception;

    /**
     * 批量保存
     *
     * @param entities 对象集合
     *
     * @return 保存后的对象集合
     */
    Collection<T> save(Collection<T> entities) throws Exception;

    /**
     * 更新
     *
     * @param entity 对象实体
     *
     * @return 更新后的对象
     */
    T update(T entity) throws Exception;

    /**
     * 批量更新
     *
     * @param entities 对象集合
     *
     * @return 更新后的对象集合
     */
    Collection<T> update(Collection<T> entities) throws Exception;

    /**
     * 删除
     *
     * @param entity 要删除的对象
     *
     * @return 返回删除的对象
     */
    T delete(T entity) throws Exception;

    /**
     * 根据Id删除对象
     *
     * @param entityClass 要删除的对象的类型
     * @param pk          对象主键
     *
     * @return 删除的对象
     */
    T delete(final Class<T> entityClass, PK pk) throws Exception;

    /**
     * 批量删除
     *
     * @param entities    对象集合
     *
     * @return 删除的对象集合
     */
    List<T> delete(List<T> entities) throws Exception;

    /**
     * 根据条件删除对象集合
     *
     * @param entityClass      要删除的对象的类型
     * @param detachedCriteria 删除条件，如果为null，则删除全部
     *
     * @return 删除的对象集合
     */
    List<T> delete(final Class<T> entityClass, DetachedCriteria detachedCriteria) throws Exception;

    /**
     * 根据某个字段查询
     * (单表操作)
     *
     * @param entityClass 要删除的对象的类型
     * @param name        字段名称
     * @param value       字段值
     */
    List<T> find(final Class<T> entityClass, String name, String value) throws Exception;

    /**
     * 根据条件查询对象集合
     *
     * @param entityClass      要查询的对象的类型
     * @param detachedCriteria 查询条件，如果为null，则查询全部
     *
     * @return 对象集合
     */
    List<T> findList(final Class<T> entityClass, DetachedCriteria detachedCriteria) throws Exception;

    /**
     * 根据条件查询对象集合,并返回指定属性(字段)
     *
     * @param entityClass      要查询的对象的类型
     * @param detachedCriteria 查询条件，如果为null，则查询全部
     * @param propertyList 查询指定的属性(字段)
     *
     * @return 对象集合
     */
    List<T> findList(final Class<T> entityClass, DetachedCriteria detachedCriteria, List<String> propertyList) throws Exception;

    /**
     * 获取前多少条数据
     *
     * @param entityClass 对象的class
     * @param criteria    条件，如果为null，则查询全部
     * @param limit       前多少条
     */
    List<T> findListLimitRows(Class<T> entityClass, DetachedCriteria criteria, Integer limit) throws Exception;

    /**
     * 分组查询
     *
     * @param entityClass      要查询的对象的类型
     * @param detachedCriteria 查询条件，如果为null，则查询全部
     * @param propertyList     group by 字段
     *
     * @return 对象集合
     */
    List<T> findListGroupBy(final Class<T> entityClass, DetachedCriteria detachedCriteria, List<String> propertyList) throws Exception;

    /**
     * 根据条件分页查询对象集合
     *
     * @param entityClass      要查询的对象的类型
     * @param detachedCriteria 查询条件，如果为null，则查询全部
     * @param pager            分页对象
     *
     * @return 对象集合
     */
    List<T> findListPager(final Class<T> entityClass, DetachedCriteria detachedCriteria, Pager pager) throws Exception;

    /**
     * 根据条件分页查询对象集合,并返回指定属性(字段)
     *
     * @param entityClass      要查询的对象的类型
     * @param detachedCriteria 查询条件，如果为null，则查询全部
     * @param pager            分页对象
     * @param propertyList     查询指定的属性(字段)
     *
     * @return 对象集合
     */
    List<T> findListPager(final Class<T> entityClass, DetachedCriteria detachedCriteria, Pager pager, List<String> propertyList) throws Exception;

    /**
     * 根据条件查询条件内的所有对象集合
     *
     * @param entityClass      要查询的对象的类型
     *
     * @return 对象集合
     */
    List<T> findAll(final Class<T> entityClass) throws Exception;

    /**
     * 根据主键查询对象
     *
     * @param entityClass 对象的class
     * @param pk          主键
     *
     * @return 对象实体
     */
    T findById(final Class<T> entityClass, PK pk) throws Exception;

    /**
     * 根据主键批量查询对象
     *
     * @param entityClass 对象的class
     * @param ids         主键集合
     *
     * @return 对象实体
     */
    List<T> findByIds(final Class<T> entityClass, PK... ids) throws Exception;

    /**
     * 根据HQL语句查询
     * @param hql    查询语句,支持连接查询和多条件查询
     * @param params 参数数组,代替hql中的"?"号
     * @return 结果集List
     */
    List<?> findByHql(String hql, Object... params);

    /**
     * 根据HQL语句查询
     * @param hql         查询语句,支持连接查询和多条件查询 例如：from User u
     * @param pager       分页对象
     * @param queryColumn 要查询的字段字符串 例如：u.id, u.name, u.age
     * @param params      参数数组,代替hql中的"?"号
     * @return 结果集List
     */
    List<?> findPagerByHql(String hql, Pager pager, String queryColumn, Object... params) throws Exception;

    /**
     * 根据SQL语句查询
     * @param sql    查询语句,支持连接查询和多条件查询
     * @param params 参数数组,代替hql中的"?"号
     * @return 结果集List
     */
    List<?> findBySQL(String sql, Object... params) throws Exception;

    /**
     * 执行原生SQL
     * @param sql
     */
    int excuteBySql(String sql) throws Exception;

    /**
     * 根据某个字段查询唯一一条数据 (单表操作)
     *
     * @param entytyClz 要删除的对象的类型
     * @param name      字段名称
     * @param value     字段值
     */
    T findUnique(final Class<T> entytyClz, String name, Object value) throws Exception;

    /**
     * 统计总记录
     *
     * @param entityClass      对象的class
     * @param detachedCriteria 条件，如果为null，则查询全部
     *
     * @return 总记录数量
     */
    Long count(final Class<T> entityClass, DetachedCriteria detachedCriteria) throws Exception;

    /**
     * 执行update 或 delete语句
     *
     * @param hql    update或delete语句，
     * @param params 参数数组,代替hql中的"?"号
     *
     * @return 更新或删除了多少数据
     */
    int executeUpdate(final String hql, Object... params);
}
